// 引入后处理扩展库EffectComposer.js
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
// 引入渲染器通道RenderPass
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
// 引入OutlinePass通道
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js';
// 引入GlitchPass通道
import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js';
//ShaderPass功能：使用后处理Shader创建后处理通道
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
//FXAA抗锯齿Shader
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js';
// SMAA抗锯齿通道
import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass.js';
// 伽马校正后处理Shader
import { GammaCorrectionShader } from "three/examples/jsm/shaders/GammaCorrectionShader.js"
// UnrealBloomPass通道可以在场景的物体中产生泛光效果，使得场景中明亮区域变得更显著，比较暗的区域也会变得稍亮。
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js'
// 后处理流程的类，它通常用于将渲染的结果输出到指定的目标，比如画布（canvas）或渲染目标（render target）
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js'
//SSRPass 可以显著提升场景的真实感，尤其是在水面、光滑表面等场景中。但是，需要注意的是，SSR是一个计算密集型的过程，可能会对性能产生影响
//用于实现屏幕空间反射（Screen Space Reflections）的后处理效果类。屏幕空间反射是一种渲染技术，
//它通过在屏幕空间内计算反射来创建更为逼真的反射效果，尤其是在处理动态场景和复杂几何体时。
import { SSRPass } from 'three/examples/jsm/postprocessing/SSRPass.js';
import * as THREE from 'three';
import { sizes } from "../system/sizes";
// import { gui } from "../system/gui";

// 后处理中使用SSRPass创建物体反射效果 使用SSRPass后在composer合成器里添加AA抗锯齿
const parameters = {
    bloomStrength: 0.3,
    bloomThreshold: 0.1,
    bloomRadius: 0.6,
}

let ssrPass = null

function initComposer(renderer, scene, camera) {

    const renderScene = new RenderPass(scene, camera);
    // 辉光处理通道
    const bloomPass = new UnrealBloomPass(
        new THREE.Vector2(window.innerWidth, window.innerHeight),
        1.5,
        0.4,
        0.85
    );
    bloomPass.threshold = parameters.bloomThreshold;
    bloomPass.strength = parameters.bloomStrength;
    bloomPass.radius = parameters.bloomRadius;
    // 抗锯齿处理通道
    const fxaaPass = new ShaderPass(FXAAShader);
    const pixelRatio = renderer.getPixelRatio();
    fxaaPass.material.uniforms['resolution'].value.x = 1 / (sizes.width * pixelRatio);
    fxaaPass.material.uniforms['resolution'].value.y = 1 / (sizes.height * pixelRatio);
    // smaapass
    // const smaaPass = new SMAAPass(window.innerWidth * pixelRatio, window.innerHeight * pixelRatio);
    // ssrpass
    ssrPass = new SSRPass({
        renderer,
        scene,
        camera,
        width: innerWidth,
        height: innerHeight,
        groundReflector: null,
        selects: []
    });
    // 输出
    const outputPass = new OutputPass();
    const composer = new EffectComposer(renderer);
    composer.addPass(renderScene);
    composer.addPass(ssrPass)
    composer.addPass(bloomPass);
    // composerEff.addPass(smaaPass)
    composer.addPass(outputPass)
    composer.addPass(fxaaPass)

    // debug
    // gui
    //     .add(parameters, "bloomStrength")
    //     .onChange((v) => {
    //         bloomPass.strength = v;
    //     })
    //     .step(0.1);
    // gui
    //     .add(parameters, "bloomRadius")
    //     .onChange((v) => {
    //         bloomPass.radius = v;
    //     })
    //     .step(0.1);
    // gui
    //     .add(parameters, "bloomThreshold")
    //     .onChange((v) => {
    //         bloomPass.threshold = v;
    //     })
    //     .step(0.1);

    return composer
}

let composerEffect = null;
let outlinePass = null;
let renderPass = null;

let copyPass = null;
let effectFXAA = null;
let smaaPass = null;
let unrealBloomPass = null;
function outlineObj (Objects, renderer, scene, camera) {

    //创建效果组合器 创建后处理对象EffectComposer，WebGL渲染器作为参数
    composerEffect = new EffectComposer(renderer)
    composerEffect.renderTarget1.texture.outputColorSpace = THREE.sRGBEncoding;
    composerEffect.renderTarget2.texture.outputColorSpace = THREE.sRGBEncoding;
    composerEffect.renderTarget1.texture.encoding = THREE.sRGBEncoding;
    composerEffect.renderTarget2.texture.encoding = THREE.sRGBEncoding;

    // 新建一个场景通道  为了覆盖到原理来的场景上
    renderPass = new RenderPass(scene, camera)
    composerEffect.addPass(renderPass)
    // 创建OutlinePass通道
    const v2 = new THREE.Vector2(window.innerWidth, window.innerHeight);
    outlinePass = new OutlinePass(
        v2,
        scene,
        camera
    )
    //定义样式
    //高亮描边发光强度
    outlinePass.edgeStrength = 5.0
    //高亮发光描边厚度
    outlinePass.edgeThickness = 5.0
    outlinePass.edgeGlow = 1.0
    outlinePass.usePatternTexture = false
    outlinePass.downSampleRatio = 2
    //模型闪烁频率控制，默认0不闪烁
    outlinePass.pulsePeriod = 2
    let color = '0x'+("#ffff00").slice(1)
    // console.log(parseInt(color))
    // 呼吸显示的颜色
    //模型描边颜色，默认白色 呼吸显示的颜色
    outlinePass.visibleEdgeColor.set(parseInt(color))
    // 呼吸消失的颜色
    outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0)
    outlinePass.clear = true

    //设置glitchPass通道
    //const glitchPass = new GlitchPass();
    //composerEffect.addPass(glitchPass);

    // 自定义的着色器通道 作为参数 设置FAXX抗锯齿通道
    effectFXAA = new ShaderPass(FXAAShader)
    // `.getPixelRatio()`获取`renderer.setPixelRatio()`设置的值
    const pixelRatio = renderer.getPixelRatio();//获取设备像素比 
    let width = window.innerWidth;
    let height = window.innerHeight;
    // width、height是canva画布的宽高度
    effectFXAA.uniforms.resolution.value.set(1 / width*pixelRatio, 1 / height*pixelRatio)
    effectFXAA.renderToScreen = true
    composerEffect.addPass(effectFXAA)

    // 创建SMAAPass抗锯齿通道
    // width、height是canva画布的宽高度
    //smaaPass = new SMAAPass(width * pixelRatio, height * pixelRatio);
    //composerEffect.addPass(smaaPass);

    // 创建伽马校正通道
    const effectColorSpaceConversion = new ShaderPass(GammaCorrectionShader)
    composerEffect.addPass(effectColorSpaceConversion)

    //创建UnrealBloomPass泛光通道
    unrealBloomPass = new UnrealBloomPass(
        new THREE.Vector2(256, 256),
        1,
        1.1,
        0.18
    )
    unrealBloomPass.renderToScreen = true
    //bloom发光强度
    unrealBloomPass.strength = 0.1;

    //将创建的通道添加到EffectComposer(效果组合器)对象中
    composerEffect.addPass(outlinePass)
    composerEffect.addPass(unrealBloomPass)
    
    outlinePass.selectedObjects = Objects

    return composerEffect

}

export { initComposer, ssrPass, outlineObj }